#include <cstdio>
#include <cstdlib>

#include "netDevice.h"
#include "common.h"

using namespace std;

netDevice::netDevice()
{
	deviceName = defaultDevice;

	configSettings = new Config(ConfigFile);

	//支持的应用程序个数
	//int programNum = configSettings->Read("programNum", 0);

	//char buff[10];
	
	//ppMap = new int[programNum + 1];

	//将programNum应用程序对应的commit port添加到ppMap中
	/*
	for(int i = 1; i <= programNum; i++)
	{
		bzero(buff, sizeof(buff));
		sprintf(buff, "commitPort%d", i);
		int port = configSettings->Read(buff, 0);
		ppMap[i] = port;
		cout<<port<<endl;
	}
	*/

	//create device
	if(deviceName == string("wifi"))
	{
		//device = new wifiDevice(ppMap);	
		device = new wifiDevice();	
		static_cast<wifiDevice *>(device)->startDevice();
	}
	else if(deviceName == string("zigbee"))
	{
		//device = new zigbeeDevice(ppMap);
		device = new zigbeeDevice();
		static_cast<zigbeeDevice *>(device)->startDevice();
	}
	else
	{
		cerr<<"no such device"<<endl;;
		exit(1);
	}
}

netDevice::~netDevice()
{
	delete ppMap;
	if(deviceName == string("wifi"))
		delete static_cast<wifiDevice *>(device);
	else if(deviceName == string("zigbee"))
		delete static_cast<zigbeeDevice *>(device);
}

void netDevice::run()
{
	int listenUDPPort = configSettings->Read("localListenPort", 0);
	
	struct sockaddr_in local_addr;

	//建立UDP服务器
	listen_sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&local_addr, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	local_addr.sin_port = htons(listenUDPPort);

	Bind(listen_sockfd, (SA *)&local_addr, sizeof(SA));

	char buff[1024];
	while(true)
	{
		bzero(buff, sizeof(buff));
		int n = Recvfrom(listen_sockfd, buff, sizeof(buff), 0, NULL, NULL);
		int nodeID;
		sscanf(buff, "%d", &nodeID);

		int i;
		for(i = 0; i < n; i++)
		{
			if(buff[i] == '#')
				break;
		}
	
		sendMessage(nodeID, buff + i + 1, n - i - 1);
	}
}

int netDevice::sendMessage(int nodeID, char* buff, int buffSize)
{
	if(deviceName == string("wifi"))
	{
		string address;
		int port;

		//将整型的节点号转化为字符串
		char idBuff[20];
		bzero(idBuff, sizeof(buff));
		sprintf(idBuff, "wifiAddress%d", nodeID);
		address = configSettings->Read(idBuff, address);

		cout<<"netDevice: send to "<<address<<" buffsize: "<<buffSize<<endl;
		
		static_cast<wifiDevice *>(device)->sendMessage(address, buff, buffSize);
	}
	else if(deviceName == string("zigbee"))
	{
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		static_cast<zigbeeDevice *>(device)->sendMessage(nodeID, buff, buffSize);
		cout<<endl;
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	}
	else
	{
		cerr<<"no device attached"<<endl;
		exit(1);
	}

	return 0;
}

string netDevice::changeDeviceTo(string newDeviceName)
{
	string oldDeviceName = deviceName;
	
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	/*
	 *改变网络设备
	 */
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	return oldDeviceName;
}

string netDevice::getDeviceName() const
{
	return deviceName;
}
